assume cs:code, ds:data

data segment
    db 180 dup(0)
data ends  

code segment
    start:
         mov ax, data
         mov ds, ax
         mov si, 0
         mov dh, 10
         mov dl, 20
         call get_str
         mov ax, 4c00h
         int 21h

get_str: push ax
get_strs:mov ah, 0
         int 16h
         cmp al, 20h
         jb not_char    ;ASCII小于20h，说明不是字符
         mov ah, 0
         call str_stack
         mov ah, 2
         call str_stack
         jmp get_strs
         
not_char:cmp ah, 0eh    ;backspace扫描码 
         je backspace
         cmp ah, 1ch
         je enter   ;enter扫描码
         jmp get_strs

backspace:mov ah, 1
          call str_stack
          mov ah, 2
          call str_stack 
          jmp get_strs

enter: mov al, 0
       mov ah, 0
       call str_stack
       mov ah, 2
       call str_stack
       pop ax
       ret

;字符栈的入栈，出栈，显示子程序
;（ah）= 功能号:0入栈（al）中是入栈字符，1出栈（al）中是出栈字符，2显示(dh),(dl)=字符串在屏幕上的行列位置
;ds:si指向字符栈空间
str_stack:jmp short str_start
          table dw char_push, char_pop, char_show
          top dw 0  ;top代表栈顶的位置，为0则栈空，否则不空。
str_start:push bx
          push es
          push di
          push dx

          cmp ah, 2
          ja str_stack_ret  ;功能号大于2就退出
          mov bx, 0
          mov bl, ah
          add bx, bx
          jmp word ptr table[bx]    ;注意char_push等最后都是jmp指令，故此处千万不能用call指令

char_push:mov bx, top
          mov [si][bx], al
          inc top
          jmp str_stack_ret

char_pop:cmp top, 0
         je str_stack_ret
         dec top
         mov bx, top
         mov al, [si][bx]
         jmp str_stack_ret

char_show:mov bx, 0b800h
          mov es, bx
          mov al, 160
          mov ah, 0
          mul dh
          mov di, ax
          add dl, dl
          mov dh,0
          add di, dx

          mov bx, 0
char_shows:cmp bx, top          ;这种处理方式比较有技巧的。栈为空时固然显示空格，当bx指向字符串最后的元素0时，也要显示空格
           jne no_empty
           mov byte ptr es:[di], ' '
           jmp str_stack_ret
no_empty:  mov al, [si][bx]
           mov es:[di], al
           mov byte ptr es:[di+2], ' '
           inc bx
           add di, 2
           jmp char_shows


str_stack_ret:pop dx
              pop di
              pop es
              pop bx
              ret

code ends
end start
